package com.jim.director.framework.log;

import com.jim.director.framework.annotation.LogFormat;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * author: Jim
 * date: 2024/10/3
 * info:
 */

public class LogItem {

    private int period;

    private Object actor;

    private Map<String, Field> fields;

    private LogFormat format;

    public LogItem(int period, Object actor, Map<String, Field> fields, LogFormat format) {
        this.period = period;
        this.actor = actor;
        this.fields = fields;
        this.format = format;
    }

    public int getPeriod() {
        return period;
    }

    public void setPeriod(int period) {
        this.period = period;
    }

    public Object getActor() {
        return actor;
    }

    public void setActor(Object actor) {
        this.actor = actor;
    }

    public Map<String, Field> getFields() {
        return fields;
    }

    public void setFields(Map<String, Field> fields) {
        this.fields = fields;
    }

    public LogFormat getFormat() {
        return format;
    }

    public void setFormat(LogFormat format) {
        this.format = format;
    }

    @Override
    public String toString() {
        switch (format) {
            case JSON:
                return toJsonFormat();
            case KEY_VALUE:
                return toKeyValueFormat();
            case TABLE:
                return toTableFormat();
            case SIMPLE:
            default:
                return toSimpleFormat();
        }
    }

    /**
     * 简单格式：actor: [类名]哈希码; fields: {属性名: 值, 属性名: 值}
     */
    private String toSimpleFormat() {
        StringBuilder sb = new StringBuilder();
        sb.append("actor: [");
        sb.append(actor.getClass().getSimpleName());
        sb.append("]");
        sb.append(actor.hashCode());
        sb.append("; fields: {");

        boolean first = true;
        for (Map.Entry<String, Field> entry : fields.entrySet()) {
            if (!first) {
                sb.append(", ");
            }
            sb.append(entry.getKey());
            sb.append(": ");
            try {
                entry.getValue().setAccessible(true);
                Object value = entry.getValue().get(actor);
                sb.append(value);
            } catch (IllegalAccessException e) {
                sb.append("N/A");
            }
            first = false;
        }
        sb.append("}");
        return sb.toString();
    }

    /**
     * JSON格式：{"actor": "类名", "hashCode": 哈希码, "属性名": 值, "属性名": 值}
     */
    private String toJsonFormat() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        sb.append("\"actor\": \"").append(actor.getClass().getSimpleName()).append("\", ");
        sb.append("\"hashCode\": ").append(actor.hashCode());

        for (Map.Entry<String, Field> entry : fields.entrySet()) {
            sb.append(", ");
            sb.append("\"").append(entry.getKey()).append("\": ");
            try {
                entry.getValue().setAccessible(true);
                Object value = entry.getValue().get(actor);
                if (value instanceof String) {
                    sb.append("\"").append(value).append("\"");
                } else {
                    sb.append(value);
                }
            } catch (IllegalAccessException e) {
                sb.append("null");
            }
        }
        sb.append("}");
        return sb.toString();
    }

    /**
     * 键值对格式：类名@哈希码 | 属性名: 值 | 属性名: 值
     */
    private String toKeyValueFormat() {
        StringBuilder sb = new StringBuilder();
        sb.append(actor.getClass().getSimpleName());
        sb.append("@");
        sb.append(actor.hashCode());

        for (Map.Entry<String, Field> entry : fields.entrySet()) {
            sb.append(" | ");
            sb.append(entry.getKey());
            sb.append(": ");
            try {
                entry.getValue().setAccessible(true);
                Object value = entry.getValue().get(actor);
                sb.append(value);
            } catch (IllegalAccessException e) {
                sb.append("N/A");
            }
        }
        return sb.toString();
    }

    /**
     * 表格格式：哈希码	属性值	属性值	...
     */
    private String toTableFormat() {
        StringBuilder sb = new StringBuilder();
        sb.append(actor.hashCode());

        for (Map.Entry<String, Field> entry : fields.entrySet()) {
            sb.append("\t");
            try {
                entry.getValue().setAccessible(true);
                Object value = entry.getValue().get(actor);
                sb.append(value);
            } catch (IllegalAccessException e) {
                sb.append("N/A");
            }
        }
        return sb.toString();
    }

    /**
     * 获取表格格式的表头
     * @return 表头字符串
     */
    public String getTableHeader() {
        if (format != LogFormat.TABLE) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        sb.append("HashCode");

        for (String fieldName : fields.keySet()) {
            sb.append("\t");
            sb.append(fieldName);
        }
        return sb.toString();
    }
}
